/* 
 * File:   circular_array_queue.h
 * Author: Marcelo Juchem <juchem at gmail dot com>
 *
 * Created on December 30, 2010, 3:35 AM
 */

#ifndef CIRCULAR_ARRAY_QUEUE_H
#    define	CIRCULAR_ARRAY_QUEUE_H

#include <cstddef>

namespace cscience {
namespace queue {

template <typename TValue>
class circular_array_queue
{
public:
	typedef TValue value_type;
	typedef size_t size_type;

private:
	value_type *m_queue;
	size_type m_offset;
	size_type m_size;
	size_type m_capacity;

public:
	circular_array_queue(size_type capacity):
		m_queue(0),
		m_offset(0),
		m_size(0),
		m_capacity(capacity)
	{
		this->m_queue = new value_type[this->m_capacity];
	}

	~circular_array_queue()
	{
		delete [] this->m_queue;
	}

	void enqueue(value_type const &value)
	{
		this->m_queue[(this->m_offset + this->m_size) % this->m_capacity] = value;

		++this->m_size;
	}

	void dequeue()
	{
		this->m_offset = (this->m_offset + 1) % this->m_capacity;

		--this->m_size;
	}

	value_type const &front() const
	{
		return this->m_queue[this->m_offset];
	}

	value_type &front()
	{
		return this->m_queue[this->m_offset];
	}

	void clear()
	{
		this->m_size = 0;
	}

	bool full() const
	{
		return this->m_size == this->m_capacity;
	}

	bool empty() const
	{
		return !this->m_size;
	}

	size_type size() const
	{
		return this->m_size;
	}
};

} // namespace cscience {
} // namespace queue {

#endif	/* CIRCULAR_ARRAY_QUEUE_H */
